#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "canmessage.h"
#include "faketemperaturemodule.h"
#include "candotemptab.h"
#include <QDebug>

const unsigned int CHARGE_COMMAND_PGN = 0x0600;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    portManager(),
    Charger(portManager),
    TempModule(0x2A, portManager),
    SecondaryTempModule(0x2B, portManager)
{
    ui->setupUi(this);
    connect(ui->OpenButton,  SIGNAL(clicked()), this, SLOT(ButtonPressed()));
    connect(&portManager, SIGNAL(LineReadyToRead()), this, SLOT(LineRecieved()));
    connect(ui->EnableFakeCharger, SIGNAL(clicked(bool)), &Charger, SLOT(setState(bool)));
    connect(ui->EnableOtherMaster, SIGNAL(clicked(bool)), &Charger, SLOT(setMasterState(bool)));
    connect(ui->SimulateChargeDone, SIGNAL(clicked(bool)), &Charger, SLOT(setChargeComplete(bool)));
    connect(ui->ClearMessages, SIGNAL(clicked()), this, SLOT(ClearChargeStateMessages()));
    connect(ui->FakeTempEnable, SIGNAL(clicked(bool)), &TempModule, SLOT(SetState(bool)));
    connect(ui->FakeTempValue, SIGNAL(textChanged()), SLOT(UpdateFakeTemp()));
    connect(ui->SecondaryFakeTempEnable, SIGNAL(clicked(bool)), &SecondaryTempModule, SLOT(SetState(bool)));
    connect(ui->SecondaryFakeTempValue, SIGNAL(textChanged()), SLOT(UpdateSecondaryFakeTemp()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::ButtonPressed()
{
    portManager.OpenPort(ui->PortInput->toPlainText());
}

void MainWindow::LineRecieved()
{
    while(portManager.HasLinesToRead())
    {
        QString newLine = portManager.ReadLine();
        if(!newLine.isEmpty())
        {
            CanMessage mess(newLine);
            if(mess.IsValid())
            {
                if(mess.GetPGN() == FakeTemperatureModule::TEMPERATURE_STATUS_PGN)
                {
                    ParseTemperatureStatus(mess);
                }
                if(mess.GetPGN() == (CHARGE_COMMAND_PGN | FakeCharger::CHARGER_SA))
                {
                    ParseChargeCommand(mess);
                }
            }
        }
    }
}

void MainWindow::ParseChargeCommand(CanMessage mess)
{
    bool shouldCharge = mess.GetData()[4] == 0;
    if(shouldCharge)
    {
        ui->ChargeCommandBar->setValue(100);
    }
    else
    {
        ui->ChargeCommandBar->setValue(0);
    }

    int commandedVoltage = (mess.GetData()[0] << 8) + (mess.GetData()[1]);
    int commandedCurrent = (mess.GetData()[2] << 8) + (mess.GetData()[3]);
    ui->ChargeCommandLabel->setText(QString("Commanded Voltage: %1 Commanded Current: %2").arg(commandedVoltage).arg(commandedCurrent));
}

void MainWindow::ClearChargeStateMessages()
{
    ui->listWidget->clear();
}

void MainWindow::UpdateFakeTemp()
{
    TempModule.SetTemperature(ui->FakeTempValue->toPlainText().toInt());
}

void MainWindow::UpdateSecondaryFakeTemp()
{
    SecondaryTempModule.SetTemperature(ui->SecondaryFakeTempValue->toPlainText().toInt());
}

void MainWindow::ParseTemperatureStatus(CanMessage mess)
{
    HandleTabStuff(mess);
    ChargerStates state = (ChargerStates)mess.GetData()[0];
    QString stateString = ConvertChargeStateEnumToText(state);
    QString temperatureString;
    for(int i = 1; i < mess.GetDataLength(); i++)
    {
        temperatureString.append(QString::number(mess.GetData()[i] - 100)).append(' ');
    }
    ui->SerialOutputLabel->setText(stateString);
    ui->listWidget->addItem(QString("%1 %2").arg(stateString, temperatureString));
    if(ui->shouldScroll->isChecked())
    {
        ui->listWidget->scrollToBottom();
    }
}

void MainWindow::HandleTabStuff(CanMessage& mess)
{
    QString SAString = QString::number(mess.GetSA());
    CanDoTemptab* tab = NULL;
    int i;
    for(i = 0; i <ui->tabWidget->count(); i++)
    {
        if(ui->tabWidget->tabText(i) == SAString)
        {
            tab = qobject_cast<CanDoTemptab*>(ui->tabWidget->widget(i));
        }
    }
    if(tab == NULL)
    {
        tab = new CanDoTemptab();
        ui->tabWidget->addTab(tab, SAString);
    }

    tab->ProcessMessage(mess);


}

QString MainWindow::ConvertChargeStateEnumToText(MainWindow::ChargerStates state)
{
    switch (state) {
    case NOT_CONNECTED:
            return "Not Connected";
        break;
    case CHARGING_NORMAL:
        return "Charging Normal";
    case CHARGE_COMPLETE:
        return "Charge Complete";
    case INTERNAL_TOO_COLD:
        return "Internal Too Cold";
    case INTERNAL_MISSING_SENSOR:
        return "Internal Missing Sensor";
    case OTHER_TOO_COLD:
        return "Other too cold";
    case OTHER_MISSING_SENSOR:
        return "Other Missing Sensor";
    case NOT_CONFIGURED_AS_MASTER:
        return "Not Configured As Master";
    default:
        return "Unknown";
    }
}


